import exif from 'exif-js'; // 读取图片的方向

/**
* 图片方向
* 问题：
* ios或相机拍出来的图片会出现旋转90°的问题，在这里获取图片的方向。
* @param file 图片对象
*/
export function pictureDirection(file) {
    let p = new Promise((resolve, reject) => {
        let img = new Image()
        img.onload = () => {
            let Orientation = ''
            exif.getData(file, function () {
                exif.getAllTags(this)
                Orientation = exif.getTag(this, 'Orientation') // 获取图片方向
                //  返回图片的base64Data，Orientation，file
                resolve({img, Orientation, file})

            })
        }

        img.onerror=()=>{
            new Error()
        }

        // 把图片读成base64数据
        let ready = new FileReader()
        /* 开始读取指定的Blob对象或File对象中的内容. 当读取操作完成时,readyState属性的值会成为DONE,如果设置了onloadend事件处理程序,则调用之.同时,result属性中将包含一个data: URL格式的字符串以表示所读取文件的内容. */
        ready.onload = (e) => {
            img.src = e.target.result
        }

        ready.onerror=()=>{
            new Error()
        }

        ready.readAsDataURL(file)
    })
    return p
}

/**
 * 压缩图片大小
 * 问题：
 * 1、ios下如果图片的尺寸超过两百万像素，图片是无法绘制到canvas上的，调用drawImage的时候不会报错，但是你用toDataURL获取图片数据的时候获取到的是空的图片数据。
 　2、ios下canvas的大小大于大概五百万像素（即宽高乘积）的时候，不仅图片画不出来，其他什么东西也都是画不出来的。
 3、png转jpg，绘制到canvas上的时候，canvas存在透明区域的话，当转成jpg的时候透明区域会变成黑色，因为canvas的透明像素默认为rgba(0,0,0,0)，所以转成jpg就变成rgba(0,0,0,1)了，也就是透明背景会变成了黑色。解决办法就是绘制之前在canvas上铺一层白色的底色。
 4、canvas的toDataURL是只能压缩jpg的，当用户上传的图片是png的话，就需要转成jpg
 5、ios或相机拍出来的图片会出现旋转90°的问题
 * @param image 图片对象
 * @param Orientation 图片方向，具体查看exif.js
 * @returns {Blob} blob对象
 */
export function compressImage (image, Orientation = 1) {
    let width = image.width,
        height = image.height;

    //针对问题2：如果图片大于四百万像素，计算压缩比并将大小压至400万以下
    let ratio;
    if ((ratio = width * height / 4000000) > 1) {
        ratio = Math.sqrt(ratio);
        width /= ratio;
        height /= ratio;
    } else {
        ratio = 1;
    }
    let canvas = window.document.createElement('canvas');
    canvas.width = width;
    canvas.height = height;

    let ctx = canvas.getContext('2d');

    //针对问题3、铺底色
    ctx.clearRect(0, 0, width, height);
    ctx.fillStyle = "#fff";
    ctx.fillRect(0, 0, width, height);


    //针对问题2，如果图片像素大于100万则使用切片绘制
    let count = 1;
    if ((count = width * height / 1000000) > 1) {
        count = ~~(Math.sqrt(count) + 1); //计算要分成多少块切片
        //计算每块切片的宽和高
        let nw = ~~(width / count),
            nh = ~~(height / count);

        let tCanvas = window.document.createElement('canvas');
        tCanvas.width = nw;
        tCanvas.height = nh;

        let tctx = tCanvas.getContext('2d');

        for (let i = 0; i < count; i++) {
            for (let j = 0; j < count; j++) {
                tctx.clearRect(0, 0, nw, nh);//每一次切片需要先擦掉之前的绘制
                tctx.fillStyle = "#fff";
                tctx.fillRect(0, 0, nw, nh);//铺上白底
                tctx.drawImage(image, i * nw * ratio, j * nh * ratio, nw * ratio, nh * ratio, 0, 0, nw, nh);

                ctx.drawImage(tCanvas, i * nw, j * nh, nw, nh);
            }
        }
    } else {
        ctx.drawImage(image, 0, 0, width, height);
    }

    let  newImgUrlBase64 = ''

    //  针对问题5、如果方向角不为1，都需要进行旋转
    if (Orientation === 6 || Orientation === 8 || Orientation === 3) {
        let newCanvas = window.document.createElement('canvas')
        switch (Orientation) {
            case 6: // 需要顺时针（向左）90度旋转
                rotateImg(canvas, 'left', newCanvas)
                break
            case 8: // 需要逆时针（向右）90度旋转
                rotateImg(canvas, 'right', newCanvas)
                break
            case 3: // 需要180度旋转
                rotateImg(canvas, 'right', newCanvas)// 转两次
                rotateImg(canvas, 'right', newCanvas)
                break
            default:
                break
        }

        //针对问题4，在转换为base64字符串的时候统一转成jpeg格式
        newImgUrlBase64 = newCanvas.toDataURL('image/jpeg', 0.5/count);//图片质量跟原图的比率固定为0.5，超过100万像素的除以count
    } else { // 不需要旋转
        //针对问题4，在转换为base64字符串的时候统一转成jpeg格式
        newImgUrlBase64 = canvas.toDataURL('image/jpeg', 0.5/count);//图片质量跟原图的比率固定为0.5，超过100万像素的除以count
    }

    //将base64的图片转换成blob对象
    let text = window.atob(newImgUrlBase64.split(",")[1]);
    let buffer = new ArrayBuffer(text.length);
    let ubuffer = new Uint8Array(buffer);

    for (let i = 0, len = text.length; i < len ; i++) {
        ubuffer[i] = text.charCodeAt(i);
    }

    let Builder = window.WebKitBlobBuilder || window.MozBlobBuilder;
    let blob;
    if (Builder) {
        let builder = new Builder();
        builder.append(buffer);
        blob = builder.getBlob('image/jpeg');
    } else {
        blob = new window.Blob([buffer], {
            type: 'image/jpeg'
        });
    }
    return blob;
}

function rotateImg (img, direction, canvas) {
    // 最小与最大旋转方向，图片旋转4次后回到原方向
    let minStep = 0
    let maxStep = 3
    if (img == null) return
    let height = img.height
    let width = img.width
    let step = 2
    if (step == null) {
        step = minStep
    }
    if (direction === 'right') {
        step++
        // 旋转到原位置，即超过最大值
        step > maxStep && (step = minStep)
    } else {
        step--
        step < minStep && (step = maxStep)
    }
    // 旋转角度以弧度值为参数
    let degree = step * 90 * Math.PI / 180
    let ctx = canvas.getContext('2d')
    switch (step) {
        case 0:
            canvas.width = width
            canvas.height = height
            ctx.drawImage(img, 0, 0)
            break
        case 1:
            canvas.width = height
            canvas.height = width
            ctx.rotate(degree)
            ctx.drawImage(img, 0, -height)
            break
        case 2:
            canvas.width = width
            canvas.height = height
            ctx.rotate(degree)
            ctx.drawImage(img, -width, -height)
            break
        case 3:
            canvas.width = height
            canvas.height = width
            ctx.rotate(degree)
            ctx.drawImage(img, -width, 0)
            break
        default:
            break
    }
}
